/* Copyright © 2010 LPRM
Universidade Federal do Espírito Santo - RNP-GT CWTools

This file is part of JoinUs!.

JoinUs! is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

JoinUs! is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with JoinUs!. If not, see <http://www.gnu.org/licenses/>. */
package com.isisufes.joinus.appserver;

import java.lang.Integer;
import java.sql.*;

public class Community extends Servlet1
{
    /**
	 * 
	 */
	private static final long serialVersionUID = 595360533669473916L;

	private static String[] cfields = { "idCommunity", "name", "description", "type", "owner" };

    private PreparedStatement ps_incomm, ps_getmem, ps_getdat, ps_create, ps_idcreat,
        ps_join, ps_owner, ps_quit, ps_edit, ps_joined, ps_search;

    protected void initStmt()
    {
        ps_incomm = DBConn.stmt("select * from JoinsCommunity where idProfile=? and idCommunity=?");
        ps_getmem = DBConn.stmt("select * from JoinsCommunity where idCommunity=?");
        ps_getdat = DBConn.stmt("select * from Community where idCommunity=?");
        ps_create = DBConn.stmt("insert into Community(name,description,type,owner) values(?,?,?,?)");
        ps_idcreat = DBConn.stmt("select currval('community_idcommunity_seq') as idc");
        ps_join = DBConn.stmt("insert into JoinsCommunity(idProfile,idCommunity) values(?,?)");
        ps_owner = DBConn.stmt("select * from Community where owner=? and idCommunity=?");
        ps_quit = DBConn.stmt("delete from JoinsCommunity where idCommunity=? and idProfile=?");
        ps_edit = DBConn.stmt("update Community set name=?,description=?,type=? where idCommunity=?");
        ps_joined = DBConn.stmt("select * from JoinsCommunity natural inner join Community where idProfile=?");
        ps_search = DBConn.stmt("select * from Community where name ~* ?");
    }

    private boolean inCommunity(String idCommunity) throws Exception
    {
        ps_incomm.clearParameters();
        ps_incomm.setInt(1, Integer.parseInt(id));  //        ps_incomm.setString(1, id);
        ps_incomm.setInt(2, Integer.parseInt(idCommunity));  //.setString(2, idCommunity);

        ResultSet rs = ps_incomm.executeQuery();
        boolean ret = rs.next();
        rs.close();

        return ret;
    }

    private boolean amOwner(String idCommunity) throws Exception
    {
        ps_owner.clearParameters();
        ps_owner.setInt(1, Integer.parseInt(id));  //.setString(1, id);
        ps_owner.setInt(2, Integer.parseInt(idCommunity));  //.setString(2, idCommunity);

        ResultSet rs = ps_owner.executeQuery();
        boolean ret = rs.next();

        rs.close();
        return ret;
    }

    private String getMembers(String idCommunity) throws Exception
    {
        ps_getmem.clearParameters();
        ps_getmem.setInt(1, Integer.parseInt(idCommunity));  // .setString(1, idCommunity);
        ResultSet rs = ps_getmem.executeQuery();

        StringBuilder sb = new StringBuilder();
        sb.append("<Members>\n");

        while (rs.next())
            sb.append("<Member>"+rs.getString("idProfile")+"</Member>");

        sb.append("</Members>\n");

        return sb.toString();
    }

    private String strCommunity(ResultSet rs, boolean members) throws Exception
    {
        StringBuilder sb = new StringBuilder();
        sb.append("<Community>\n");

        for (String field: cfields)
            sb.append("<"+field+">"+rs.getString(field)+"</"+field+">\n");

        if (members) sb.append(getMembers(rs.getString("idCommunity")));

        sb.append("</Community>\n");

        return sb.toString();
    }

    private String strCommunities(ResultSet rs) throws Exception
    {
        StringBuilder sb = new StringBuilder();

        sb.append("<Communities>\n");
        while (rs.next())
            sb.append(strCommunity(rs, false));
        sb.append("</Communities>\n");

        rs.close();
        return sb.toString();
    }

    private String getData(String idCommunity) throws Exception
    {
        if (!inCommunity(idCommunity)) throw new Exception("not allowed - not a member");

        ps_getdat.clearParameters();
        ps_getdat.setInt(1, Integer.parseInt(idCommunity));  // .setString(1, idCommunity);

        ResultSet rs = ps_getdat.executeQuery();
        if (!rs.next()) throw new Exception("invalid id");

        String ret = strCommunity(rs, true);

        rs.close();
        return ret;
    }

    private String idcreat() throws Exception
    {
        ResultSet rs = ps_idcreat.executeQuery();
        if (!rs.next()) throw new Exception("Catastrophic Database Failure");
        String idCommunity = rs.getString("idc");
        rs.close();

        return idCommunity;
    }

    private String create(String name, String description, String type)
        throws Exception
    {
        ps_create.clearParameters();
        ps_create.setString(1, name);
        ps_create.setString(2, description);
        ps_create.setInt(3, Integer.parseInt(type));  // .setString(3, type);
        ps_create.setInt(4, Integer.parseInt(id));  //        ps_create.setString(4, id);
        ps_create.executeUpdate();

        String idCommunity = idcreat();
        join(idCommunity);

        return idCommunity;
    }

    private String join(String idCommunity) throws Exception
    {
        if (inCommunity(idCommunity)) return "";

        ps_join.clearParameters();
        ps_join.setInt(1, Integer.parseInt(id));  //.setString(1, id);
        ps_join.setInt(2, Integer.parseInt(idCommunity));  //.setString(2, idCommunity);
        ps_join.executeUpdate();

        return "";
    }

    private String quit(String idCommunity, String target) throws Exception
    {
        if (target == null) target = id;
        else if (!amOwner(idCommunity)) throw new Exception("not allowed");

        ps_quit.clearParameters();
        ps_quit.setInt(1, Integer.parseInt(idCommunity));  // .setString(1, idCommunity);
        ps_quit.setInt(2, Integer.parseInt(target));  // .setString(2, target);
        ps_quit.executeUpdate();

        return "";
    }

    private String edit(String idCommunity, String name, String description, String type)
        throws Exception
    {
        if (!amOwner(idCommunity)) throw new Exception("not allowed");

        ps_edit.clearParameters();
        ps_edit.setString(1, name);
        ps_edit.setString(2, description);
        ps_edit.setInt(3, Integer.parseInt(type));  // .setString(3, type);
        ps_edit.setInt(4, Integer.parseInt(idCommunity));  // .setString(4, idCommunity);
        ps_edit.executeUpdate();

        return "";
    }

    private String getJoined() throws Exception
    {
        ps_joined.clearParameters();
        ps_joined.setInt(1, Integer.parseInt(id));  //.setString(1, id);

        return strCommunities(ps_joined.executeQuery());
    }

    private String search(String name) throws Exception
    {
        ps_search.clearParameters();
        ps_search.setString(1, name);

        return strCommunities(ps_search.executeQuery());
    }

    protected String dispatch(String action) throws Exception
    {
        String ret = null;

        if (action.equals("getData"))
            ret = getData(arg("idCommunity"));

        if (action.equals("getMembers"))
            ret = getMembers(arg("idCommunity"));

        if (action.equals("create"))
            ret = create(arg("name"), arg("description"), arg("type"));

        if (action.equals("join"))
            ret = join(arg("idCommunity"));

        if (action.equals("quit"))
            ret = quit(arg("idCommunity"), argn("target"));

        if (action.equals("edit"))
            ret = edit(arg("idCommunity"), arg("name"), arg("description"), arg("type"));

        if (action.equals("getJoined"))
            ret = getJoined();

        if (action.equals("search"))
            ret = search(arg("name"));

        return ret;
    }
}
